package org.dicr.gui;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;

import org.dicr.event.*;

/***********************************************************************************************************************
 * <p>
 * Title: DiJaWo
 * </p>
 * <p>
 * Description: Dicr Java Utilites
 * </p>
 * <p>
 * Copyright: (C) by Dicr 2002
 * </p>
 * <p>
 * Company: Dicr
 * </p>
 * 
 * @author Igor A Tarasov me@dicr.dn.ua
 * @version 030111
 **********************************************************************************************************************/
public class MessagesPane extends JEditorPane {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected Element paragraph = null;

	protected JPopupMenu menu = new JPopupMenu();

	protected JMenuItem copyItem = new JMenuItem("Копировать");

	protected JMenuItem clearItem = new JMenuItem("Очистить");

	/*******************************************************************************************************************
     * Конструктор
     ******************************************************************************************************************/
	public MessagesPane() {
		super("text/html", "");
		try {
			jbInit();
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
	}

	/*******************************************************************************************************************
     * Инициализация
     ******************************************************************************************************************/
	private void jbInit() throws Exception {
		this.setPreferredSize(new Dimension(50, 50));
		this.setEditable(false);
		this.setAutoscrolls(true);
		this.setToolTipText("Окно сообщений");
		this.addMouseListener(new MesMouseListener());
		this.menu.add(this.clearItem);
		this.menu.add(this.copyItem);
		this.menu.add(this.clearItem);
		this.copyItem.addActionListener(new MenuListener());
		this.clearItem.addActionListener(new MenuListener());

		HTMLDocument doc = (HTMLDocument) getDocument();
		Element html = doc.getDefaultRootElement();
		Element body = null;
		for (int i = 0; i < html.getElementCount(); i++) {
			Element el = html.getElement(i);
			if (el.getName().equalsIgnoreCase("body")) {
				body = el;
				break;
			}
		}
		if (body == null) throw new IllegalStateException("Не удается найти HTML тэг BODY");
		doc.setInnerHTML(body, "<P align=left></P>");
		this.paragraph = body.getElement(0);
	}

	/*******************************************************************************************************************
     * Добавляет сообщение
     ******************************************************************************************************************/
	public synchronized void addMessage(String message, boolean error) {
		try {
			StringTokenizer tok = new StringTokenizer(message, "\n", true);
			StringBuffer buf = new StringBuffer();
			if (error) buf.append("<FONT color=red>");
			while (tok.hasMoreTokens())
				buf.append(tok.nextToken() + "<BR>");
			if (error) buf.append("</FONT>");
			((HTMLDocument) getDocument()).insertBeforeEnd(this.paragraph, buf.toString() + "\n");
			this.scrollRectToVisible(new Rectangle(new Point(this.getWidth() - 10, this.getHeight() - 10)));
			this.repaint();
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
	}

	/*******************************************************************************************************************
     * Добавляет сообщение
     ******************************************************************************************************************/
	public void addMessage(String message) {
		addMessage(message, false);
	}

	/*******************************************************************************************************************
     * Добавляет сообщение об ошибке
     ******************************************************************************************************************/
	public void addErrorMessage(String error) {
		if (error == null) return;
		addMessage(error.toString(), true);
	}

	public void addErrorMessage(Throwable ex) {
		if (ex == null) throw new IllegalArgumentException("null ex");
		this.addMessage(ex.getLocalizedMessage(), true);
	}

	/*******************************************************************************************************************
     * Добавляет сообщения об ошибках
     ******************************************************************************************************************/
	public void addErrorMessages(List<? extends Object> errors) {
		if (errors == null) return;
		for (Object err : errors) {
			this.addErrorMessage(err.toString());
		}
	}

	/*******************************************************************************************************************
     * ######################################################################### Слушатель мыши
     * #########################################################################
     ******************************************************************************************************************/
	class MesMouseListener extends MouseAdapter {
		/***************************************************************************************************************
         * Показать меню
         **************************************************************************************************************/
		protected synchronized void showPopUp(MouseEvent e) {
			if (!e.isPopupTrigger()) return;
			MessagesPane.this.menu.show(MessagesPane.this, e.getX(), e.getY());
		}

		/***************************************************************************************************************
         * Мышка нажата
         **************************************************************************************************************/
		@Override
		public void mousePressed(MouseEvent e) {
			showPopUp(e);
		}

		/***************************************************************************************************************
         * Мышка отжата
         **************************************************************************************************************/
		@Override
		public void mouseReleased(MouseEvent e) {
			showPopUp(e);
		}
	}

	/*******************************************************************************************************************
     * ######################################################################### Слушатель событий меню
     * #########################################################################
     ******************************************************************************************************************/
	class MenuListener implements ActionListener {
		@Override
        public void actionPerformed(ActionEvent e) {
			try {
				if (getSelectionEnd() == 0 || e.getSource() == MessagesPane.this.clearItem) selectAll();
				setEditable(true);
				if (e.getSource() == MessagesPane.this.copyItem) copy();
				else cut();
			} catch (Exception ex) {
				DicrExceptionHandler.handleException(ex, this);
			} finally {
				setEditable(false);
				select(0, 0);
			}
		}
	}
}
